AWS SESのバウンスを見やすい形でSlackに通知してみる
みなさん AWS SES(以下 SES)のバウンス通知の実装はどうしているでしょうか?
メールで通知する場合は比較的簡単に設定できるのですが、Slack への通知は一手間かかります。
今回は Slack でバウンスの通知を整形し、以下のような見やすい形で通知してみます。
作成した構成
バウンスのイベントを EventBridge で取得し、Chatbot 経由で Slack へ通知します。
入力トランスフォーマーの整形を入れないと、以下のような通知になるのですが、これだと情報が足りません。
バウンスが発生したことは分かりますが、どの送信元メールなのか、原因は何かなど、調査に必要な情報が欲しくなりますよね。
そのため EventRule 内で必要な情報を取得・整形した上で Slack へ通知する形を取りました。
やってみる
CloudFormation のテンプレートを作成したので、試したい方はこちらをご利用ください。
前提として以下の環境で利用してください。
- Slack のワークスペース連携済み
- 検証済みの SES ID が存在している
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
Prefix:
Type: String
Description: Prefix for SES
Default: ses-bounce
BounceSlackChannel:
Type: String
SlackWorkspace:
Type: String
Resources:
SESConfigurationSet:
Type: "AWS::SES::ConfigurationSet"
Properties:
Name: !Sub "${Prefix}-configuration-set"
SendingOptions:
SendingEnabled: true
SESEventDestinationEventBridge:
Type: "AWS::SES::ConfigurationSetEventDestination"
Properties:
ConfigurationSetName: !Ref SESConfigurationSet
EventDestination:
Name: !Sub "${Prefix}-destination-eventbridge"
Enabled: true
MatchingEventTypes:
- "bounce"
EventBridgeDestination:
EventBusArn: !Sub "arn:aws:events:${AWS::Region}:${AWS::AccountId}:event-bus/default"
SESBounceTopic:
Type: AWS::SNS::Topic
Properties:
DisplayName: "SES Bounce Topic"
TopicName: !Sub "${Prefix}-ses-bounce-topic"
SESBounceTopicPolicy:
Type: AWS::SNS::TopicPolicy
Properties:
Topics:
- !Ref SESBounceTopic
PolicyDocument:
Version: "2008-10-17"
Statement:
- Sid: "DefaultSNSPolicy"
Effect: Allow
Principal:
AWS: "*"
Action:
- SNS:GetTopicAttributes
- SNS:SetTopicAttributes
- SNS:AddPermission
- SNS:RemovePermission
- SNS:DeleteTopic
- SNS:Subscribe
- SNS:ListSubscriptionsByTopic
- SNS:Publish
Resource: !Ref SESBounceTopic
Condition:
StringEquals:
AWS:SourceOwner: !Ref AWS::AccountId
- Sid: "AllowEventBridgeToPublishToSNS"
Effect: Allow
Principal:
Service: events.amazonaws.com
Action: SNS:Publish
Resource: !Ref SESBounceTopic
SESBounceEventRule:
Type: AWS::Events::Rule
Properties:
Name: !Sub "${Prefix}-ses-bounce-rule"
Description: "Rule to capture SES bounce events and notify via Chatbot"
State: ENABLED
EventPattern:
source:
- aws.ses
detail-type:
- "Email Bounced"
Targets:
- Arn: !Ref SESBounceTopic
Id: "ses-bounce-topic"
InputTransformer:
InputPathsMap:
bounceType: "$.detail.bounce.bounceType"
bounceSubType: "$.detail.bounce.bounceSubType"
emailAddress: "$.detail.bounce.bouncedRecipients[0].emailAddress"
status: "$.detail.bounce.bouncedRecipients[0].status"
diagnosticCode: "$.detail.bounce.bouncedRecipients[0].diagnosticCode"
messageId: "$.detail.mail.messageId"
source: "$.detail.mail.source"
timestamp: "$.detail.bounce.timestamp"
subject: "$.detail.mail.commonHeaders.subject"
InputTemplate: |
{
"version":"1.0",
"source":"custom",
"content":{
"textType": "client-markdown",
"title":"📧 SES バウンスメール検知",
"description":"以下のメール送信でバウンスが発生しました\n\n*バウンス情報:*\n• バウンスタイプ: <bounceType>\n• バウンスサブタイプ: <bounceSubType>\n• エラーコード: <status>\n• エラー診断: <diagnosticCode>\n\n*送信情報:*\n• 送信元: <source>\n• 送信先: <emailAddress>\n• 件名: <subject>\n• メッセージID: <messageId>\n• 発生時刻: <timestamp>",
"nextSteps":[
"バウンスタイプに応じて以下の対応を検討してください:",
"- Permanent: 送信先アドレスの無効化や修正",
"- Transient: 一時的な問題として監視"
]
}
}
EventBridgeRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- events.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: ChatbotInvokePolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- chatbot:*
Resource: "*"
ChatbotSlackBounceChannel:
Type: AWS::Chatbot::SlackChannelConfiguration
Properties:
ConfigurationName: !Sub "${Prefix}-bounce-notification"
IamRoleArn: !GetAtt ChatbotRole.Arn
SlackChannelId: !Ref BounceSlackChannel
SlackWorkspaceId: !Ref SlackWorkspace
GuardrailPolicies:
- "arn:aws:iam::aws:policy/ReadOnlyAccess"
SnsTopicArns:
- !Ref SESBounceTopic
ChatbotRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- chatbot.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/ReadOnlyAccess
SESに設定セットを紐づける
CloudFormation で作成した設定セットをバウンス通知を設定したい ID に紐づけます。
Slackの通知先チャンネルにAWSアプリを招待
プライベートチャンネルには AWS アプリを招待する必要があります。
/invite @aws
もし対象のチャンネルに招待していなければ招待しておきましょう。
バウンスメールの通知確認
準備が整ったので、バウンスメールを発生させて通知が飛ぶか確認してみます。
設定セットを紐づけた ID からテストメールを送信しましょう。シナリオから「バウンス」を選択し、件名と本文は任意のものを入れます。
これでメールを送信すると、Slack へ通知されるはずです。
バウンス自体の情報と送信したメールの詳細情報が通知されます。
注意点
SESイベントはデフォルトでは送信されない
SES イベントはデフォルトでは EventRule で取得できません。
イベントを送信するには、SES の設定セットで「イベントの送信先」を設定しないといけない点に注意してください。今回はテンプレートの中で設定していますが、手動で作成する場合は気をつけましょう。
フィードバック通知からSlackへの通知はできない
ID 単位で設定できるフィードバック通知ですが、ここの Bounce に SNS トピックを設定して Chatbot 経由での通知はできません。イベント形式が EventBridge 経由とは異なるため Chatbot が未対応だと思われます。
メールでの通知であればここに設定でも良いですが、Chatbot を使って通知したい場合は設定セットのイベント送信先を利用しましょう。
終わりに
AWS SES のバウンスを見やすい形で Slack に通知してみました。大量のメール通知を行う場合は Slack での確認は難しいですが、少量であれば Slack での運用も可能です。
バウンスの通知だけでなく、詳細情報としてVirtual Deliverability Managerを有効化したり、ログを取得しておくことも重要です。しっかり設定しておきましょう。
メールよりは Slack 上の方が気づきやすく運用しやすいと思いますので、SES を運用する際の一助となれば幸いです。